const jwt = require('jsonwebtoken');

const errorType = require('../constants/error-type');
const authService = require('../service/user.service');
const md5password = require('../utils/password-handle');
const {PUBLIC_KEY} = require('../app/config');

const verifyLogin = async (ctx, next) => {
  const {name, password} = ctx.request.body;
  // console.log(name, password);

  // 判断用户名和密码是否为空
  if (!name || !password || name === '' || password === '') {
    const error = new Error(errorType.NAME_OR_PASSWORD_NOT_EMPTY);
    return ctx.app.emit('error', error, ctx);
  }

  const result = await authService.getUserByName(name);
  const user = result[0];
  
  // 判断数据库是否含有当前注册用户名
  if (!user) {
    const error = new Error(errorType.USER_NON_EXISTENCE);
    return ctx.app.emit('error', error, ctx);
  }

  // 判断密码是否相同
  if (md5password(password) !== user.password) {
    const error = new Error(errorType.PASSWORD_IS_ERROR);
    return ctx.app.emit('error', error, ctx);
  }

  // 挂载用户
  ctx.user = user;
  
  await next();
}

// 验证token是否合法
const verifyAuth = async (ctx, next) => {
  // console.log(ctx.header);
  const authorization = ctx.header.authorization;
  
  if (!authorization) {
    const error = new Error(errorType.TOKEN_ERROR);
    return ctx.app.emit('error', error, ctx);
  }
  
  const token = authorization.replace('Bearer ', '');
  
  try {
    const result = jwt.verify(token, PUBLIC_KEY, {
      algorithms: ['RS256']
    })

    // 挂载用户
    ctx.user = result;
    
    await next();
  } catch (err) {
    const error = new Error(errorType.UNAUTHORIZATION);
    return ctx.app.emit('error', error, ctx);
  }
}

// 验证用户是否拥有修改内容权限
const verifyPermission = async(ctx, next) => {
  const [resourceKey] = Object.keys(ctx.params);
  const tableName = resourceKey.replace('Id', '');
  const resourceId = ctx.params[resourceKey];
  const {id} = ctx.user;

  const isPermission = await authService.isPermission(tableName, resourceId, id);

  if (!isPermission) {
    const error = new Error(errorType.NO_PERMISSION);
    return ctx.app.emit('error', error, ctx);
  }

  await next();
}

module.exports = {
  verifyLogin,
  verifyAuth,
  verifyPermission
}